package com.luhuiguo.cms.server.service.impl;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import org.springframework.stereotype.Service;

import com.luhuiguo.cms.server.entity.Attachment;
import com.luhuiguo.cms.server.service.AttachmentService;
import com.luhuiguo.cms.server.service.restriction.AttachmentFilter;
import com.luhuiguo.cms.shared.model.AttachmentModel;

@Service
public class AttachmentServiceImpl implements AttachmentService {

    @PersistenceUnit
    private EntityManagerFactory emf;

    @Override
    public void deleteAttachment(Long id) {
        EntityManager em = emf.createEntityManager();
        try {
            em.remove(em.find(Attachment.class, id));
        } finally {
            em.close();
        }

    }

    @Override
    public void deleteAttachmentByArticleId(Long articleId) {
        List<Attachment> list = findAttachmentByArticleId(articleId);
        for (Attachment item : list) {
            deleteAttachment(item.getId());
        }

    }

    @Override
    public Attachment getAttachment(Long id) {

        EntityManager em = emf.createEntityManager();
        try {
            return em.find(Attachment.class, id);
        } finally {
            em.close();
        }
    }

    @Override
    public void saveAttachment(Attachment attachment) {
        EntityManager em = emf.createEntityManager();
        try {
            if (attachment.isImage()) {
                attachment.setType(AttachmentModel.TYPE_IMAGE);
            } else {
                attachment.setType(AttachmentModel.TYPE_ATTACH);
            }

            attachment.setLastModified(new Date());
            em.persist(attachment);
        } finally {
            em.close();
        }
    }

    @Override
    public Attachment updateAttachment(Attachment attachment) {
        EntityManager em = emf.createEntityManager();
        try {
            attachment.setLastModified(new Date());
            return em.merge(attachment);
        } finally {
            em.close();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Attachment> findAttachmentByArticleId(Long articleId, int... rowStartIdxAndCount) {
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em
                    .createQuery("SELECT t FROM Attachment t WHERE t.articleId = :articleId ORDER BY t.lastModified");
            q.setParameter("articleId", articleId);

            if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
                int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
                if (rowStartIdx > 0) {
                    q.setFirstResult(rowStartIdx);
                }
                if (rowStartIdxAndCount.length > 1) {
                    int rowCount = Math.max(0, rowStartIdxAndCount[1]);
                    if (rowCount > 0) {
                        q.setMaxResults(rowCount);
                    }
                }
            }
            List<Attachment> list = q.getResultList();
            list.size();

            return list;
        } finally {
            em.close();
        }
    }

    @Override
    public int getAttachmentCountByArticleId(Long articleId) {
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em.createQuery("SELECT COUNT(t) FROM Attachment t WHERE t.articleId = :articleId");
            q.setParameter("articleId", articleId);

            return (Integer) q.getSingleResult();
        } finally {
            em.close();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Attachment> findAttachmentByArticleIdAndType(Long articleId, int type) {

        EntityManager em = emf.createEntityManager();
        try {
            Query q = em
                    .createQuery("SELECT t FROM Attachment t WHERE t.articleId = :articleId and t.type = :type ORDER BY t.lastModified");
            q.setParameter("articleId", articleId);
            q.setParameter("type", type);
            List<Attachment> list = q.getResultList();
            list.size();

            return list;
        } finally {
            em.close();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Attachment> findAttachments(AttachmentFilter filter, int... rowStartIdxAndCount) {
        EntityManager em = emf.createEntityManager();
        try {
            String queryStr = "SELECT FROM Attachment ORDER BY lastModified desc";
            if (null != filter) {
                queryStr = filter.toQueryString();
            }
            Query q = em.createQuery(queryStr);

            if (null != filter) {
                filter.setParameters(q);

            }

            if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
                int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
                if (rowStartIdx > 0) {
                    q.setFirstResult(rowStartIdx);
                }
                if (rowStartIdxAndCount.length > 1) {
                    int rowCount = Math.max(0, rowStartIdxAndCount[1]);
                    if (rowCount > 0) {
                        q.setMaxResults(rowCount);
                    }
                }
            }
            List<Attachment> list = q.getResultList();
            list.size();
            return list;
        } finally {
            em.close();
        }
    }

    @Override
    public int getAttachmentCount(AttachmentFilter filter) {
        EntityManager em = emf.createEntityManager();
        try {
            String queryStr = "SELECT COUNT() FROM Attachment";
            if (null != filter) {
                queryStr = filter.toCountString();

            }
            Query q = em.createQuery(queryStr);
            if (null != filter) {
                filter.setParameters(q);

            }
            return (Integer) q.getSingleResult();
        } finally {
            em.close();
        }
    }

}
